/*----------------------------------------------------------------------------*
 *                                                                            *
                                n w - g t p v 2 c
      G P R S   T u n n e l i n g    P r o t o c o l   v 2 c    S t a c k
 *                                                                            *
 *                                                                            *
   Copyright (c) 2010-2011 Amit Chawre
   All rights reserved.
 *                                                                            *
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
 *                                                                            *
   1. Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
   3. The name of the author may not be used to endorse or promote products
      derived from this software without specific prior written permission.
 *                                                                            *
   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  ----------------------------------------------------------------------------*/

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include "bstrlib.h"

#include "NwGtpv2c.h"
#include "NwGtpv2cIe.h"
#include "NwGtpv2cLog.h"
#include "NwGtpv2cMsg.h"
#include "NwGtpv2cPrivate.h"
#include "NwLog.h"
#include "NwTypes.h"
#include "NwUtils.h"
#include "dynamic_memory_check.h"
#include "log.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct NwGtpv2cMsgIeInfo {
  uint8_t ieType;
  uint8_t ieMinLength;
  uint8_t ieInstance;
  uint8_t iePresence;
  struct NwGtpv2cMsgIeInfo *pGroupedIeInfo;
} NwGtpv2cMsgIeInfoT;

static NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeCreatedIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_TFT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_THREE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_FOUR,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_LEVEL_QOS, 18, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    //   { NW_GTPV2C_IE_IMSI           ,       0, NW_GTPV2C_IE_INSTANCE_ZERO  ,
    //   NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeRemovedIeInfoTbl[] = {
    {NW_GTPV2C_IE_IMSI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT echoRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createSessionReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_IMSI, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_MSISDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_MEI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RAT_TYPE, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_INDICATION, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_APN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_SELECTION_MODE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PDN_TYPE, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PAA, 5, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_AMBR, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY,
     createSessionReqBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
     createSessionReqBearerCtxtTobeRemovedIeInfoTbl},
    {NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_RECOVERY, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CHARGING_CHARACTERISTICS, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_LDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_LDN, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createBearerReqBearerCtxtTobeCreatedIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_TFT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_THREE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_FOUR,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_LEVEL_QOS, 22, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_CHARGING_ID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_FLAGS, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createBearerReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_PROCEDURE_TRANSACTION_ID, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY,
     createBearerReqBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CHANGE_REPORTING_ACTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CSG_INFORMATION_REPORTING_ACTION, 0,
     NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL,
     NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT updateBearerReqBearerCtxtTobeCreatedIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_TFT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_LEVEL_QOS, 22, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CHARGING_ID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_FLAGS, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT updateBearerReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_PROCEDURE_TRANSACTION_ID, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY,
     updateBearerReqBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_AMBR, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CHANGE_REPORTING_ACTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CSG_INFORMATION_REPORTING_ACTION, 0,
     NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL,
     NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT
    deleteBearerReqFailedBearerCtxtTobeCreatedIeInfoTbl[] = {
        {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
         NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
        {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
         NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
        /*
         * Do not add below this
         */
        {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerCmdBearerCtxtIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_FLAGS, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerFailureIndBearerCtxtIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL,
     deleteBearerReqFailedBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_PROCEDURE_TRANSACTION_ID, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerCmdIeInfoTbl[] = {
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, deleteBearerCmdBearerCtxtIeInfoTbl},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerFailureIndIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY,
     deleteBearerFailureIndBearerCtxtIeInfoTbl},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT bearerResourceCmdIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PROCEDURE_TRANSACTION_ID, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FLOW_QOS, 21, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_TAD, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT bearerResourceFailureIndIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PROCEDURE_TRANSACTION_ID, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createBearerRspBearerCtxtTobeCreatedIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_THREE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_FOUR,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    /* Warning: NW_GTPV2C_IE_FTEID Up to instance 9 */
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createBearerRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY,
     createBearerRspBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_RECOVERY, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_UE_TIME_ZONE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_ULI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT updateBearerRspBearerCtxtTobeCreatedIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    /* Warning: NW_GTPV2C_IE_FTEID Up to instance 9 */
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT updateBearerRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY,
     updateBearerRspBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RECOVERY, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_UE_TIME_ZONE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_ULI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerRspBearerCtxtTobeCreatedIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    /* Warning: NW_GTPV2C_IE_FTEID Up to instance 9 */
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteBearerRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_EBI, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL,
     deleteBearerRspBearerCtxtTobeCreatedIeInfoTbl},
    {NW_GTPV2C_IE_RECOVERY, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQ_CSID, 0, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_UE_TIME_ZONE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_ULI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT modifyBearerReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_MEI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_ULI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RAT_TYPE, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT releaseAccessBearersReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_EBI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_NODE_TYPE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteSessionReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_EBI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_ULI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT createSessionRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PAA, 5, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT modifyBearerRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_EBI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PAA, 5, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT releaseAccessBearersRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT deleteSessionRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PCO, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

/* Message sent over s10 interface */
static NwGtpv2cMsgIeInfoT identificationReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_GUTI, 6, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_COMPLETE_REQUEST_MESSAGE, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_SERVING_NETWORK, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT identificationRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_IMSI, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_MM_CONTEXT, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT contextReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_IMSI, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_GUTI, 5, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_ULI, 7, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PTMSI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_COMPLETE_REQUEST_MESSAGE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_UDP_SOURCE_PORT_NUMBER, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RAT_TYPE, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_HOP_COUNTER, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_LDN, 3, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT contextRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_IMSI, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_MM_CONTEXT, 4, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PDN_CONNECTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FQDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_IP_ADDRESS, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_IP_ADDRESS, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RFSP_INDEX, 2, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_RFSP_INDEX, 2, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_UE_TIME_ZONE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_LDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT contextAckIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT forwardRelocationReqIeInfoTbl[] = {
    {NW_GTPV2C_IE_IMSI, 8, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_PDN_CONNECTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FQDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_MM_CONTEXT, 4, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_TARGET_IDENTIFICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_IP_ADDRESS, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_IP_ADDRESS, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_SOURCE_IDENTIFICATION, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_SELECTED_PLMN_ID, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_RFSP_INDEX, 2, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_RFSP_INDEX, 2, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_CSG_ID, 4, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_CSG_MEMBERSHIP_INDICATION, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_UE_TIME_ZONE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_LDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_ADDITIONAL_MM_CTXT_FOR_SRVCC, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_ADDITIONAL_FLAGS_FOR_SRVCC, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_MSISDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT forwardRelocationRspIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_FTEID, 9, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_BEARER_CONTEXT, 0, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_ONE,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_TWO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_LDN, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT forwardAccessContextNtfIeInfoTbl[] = {
    {NW_GTPV2C_IE_F_CONTAINER, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT forwardAccessContextAckIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT forwardRelocationCompleteNtfIeInfoTbl[] = {
    {NW_GTPV2C_IE_INDICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

static NwGtpv2cMsgIeInfoT forwardRelocationCompleteAckIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_RECOVERY, 1, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

/** Paging related signaling. */
static NwGtpv2cMsgIeInfoT downlinkDataNtfIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

/** Relocation Cancel Request. */
static NwGtpv2cMsgIeInfoT relocationCancelRequestIeInfoTbl[] = {
    {NW_GTPV2C_IE_IMSI, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
    {NW_GTPV2C_IE_F_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

/** Relocation Cancel Response. */
static NwGtpv2cMsgIeInfoT relocationCancelResponseIeInfoTbl[] = {
    {NW_GTPV2C_IE_CAUSE, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},
    {NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO,
     NW_GTPV2C_IE_PRESENCE_OPTIONAL, NULL},

    /*
     * Do not add below this
     */
    {0, 0, 0}};

/*----------------------------------------------------------------------------*
                       P R I V A T E     F U N C T I O N S
  ----------------------------------------------------------------------------*/

/*‘nwGtpv2cMsgGroupedIeCount’ defined but not used [-Wunused-function]
 * static uint32_t                         nwGtpv2cMsgGroupedIeCount (
NwGtpv2cMsgIeInfoT * pMsgIeInfo) {
  uint32_t                                count = 0;
  NwGtpv2cMsgIeInfoT                     *pGroupedIeInfo = pMsgIeInfo;

  while (pGroupedIeInfo++) {
    if (pGroupedIeInfo->ieType == 0) {
      break;
    }

    count++;
  }

  return count;
}*/

static nw_rc_t nwGtpv2cMsgIeParseInfoUpdate(nw_gtpv2c_msg_ie_parse_info_t *thiz,
                                            NwGtpv2cMsgIeInfoT *pMsgIeInfo) {
  uint32_t i, j;

  for (i = 0; pMsgIeInfo[i].ieType; i++) {
    if (pMsgIeInfo[i].pGroupedIeInfo) {
      nw_gtpv2c_grouped_ie_parse_info_t *pMsgIeParseInfo;

      NW_GTPV2C_MALLOC(thiz->hStack, sizeof(nw_gtpv2c_grouped_ie_parse_info_t),
                       pMsgIeParseInfo, nw_gtpv2c_grouped_ie_parse_info_t *);
      pMsgIeParseInfo->groupedIeType = pMsgIeInfo[i].ieType;
      pMsgIeParseInfo->hStack = thiz->hStack;

      for (j = 0; pMsgIeInfo[i].pGroupedIeInfo[j].ieType; j++) {
        pMsgIeParseInfo
            ->ieParseInfo[pMsgIeInfo[i].pGroupedIeInfo[j].ieType]
                         [pMsgIeInfo[i].pGroupedIeInfo[j].ieInstance]
            .ieMinLength = pMsgIeInfo[i].pGroupedIeInfo[j].ieMinLength;
        pMsgIeParseInfo
            ->ieParseInfo[pMsgIeInfo[i].pGroupedIeInfo[j].ieType]
                         [pMsgIeInfo[i].pGroupedIeInfo[j].ieInstance]
            .iePresence = pMsgIeInfo[i].pGroupedIeInfo[j].iePresence;

        if (pMsgIeInfo[i].pGroupedIeInfo[j].iePresence ==
            NW_GTPV2C_IE_PRESENCE_MANDATORY)
          pMsgIeParseInfo->mandatoryIeCount++;
      }

      thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance]
          .pGroupedIeInfo = pMsgIeParseInfo;
    } else {
      thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance]
          .pGroupedIeInfo = NULL;
    }

    thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance]
        .iePresence = pMsgIeInfo[i].iePresence;
    thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance]
        .ieMinLength = pMsgIeInfo[i].ieMinLength;

    if (pMsgIeInfo[i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
      thiz->mandatoryIeCount++;
  }

  return NW_OK;
}

static nw_rc_t nwGtpv2cMsgGroupedIeParse(
    NW_IN nw_gtpv2c_grouped_ie_parse_info_t *thiz, NW_IN uint8_t ieType,
    NW_IN uint16_t ieLength, NW_IN uint8_t ieInstance,
    NW_IN uint8_t *pIeValue) {
  NW_ASSERT(thiz);
  OAILOG_DEBUG(
      LOG_GTPV2C,
      "Received grouped IE %u with instance %u of length %u in msg-type %u!\n",
      ieType, ieInstance, ieLength, thiz->groupedIeType);
  return NW_OK;
}

/*----------------------------------------------------------------------------*
                         P U B L I C   F U N C T I O N S
  ----------------------------------------------------------------------------*/

/**
   Constructor
   @return Pointer to the object on success.
*/

nw_gtpv2c_msg_ie_parse_info_t *nwGtpv2cMsgIeParseInfoNew(
    nw_gtpv2c_stack_handle_t hStack, uint8_t msgType) {
  nw_rc_t rc;
  nw_gtpv2c_msg_ie_parse_info_t *thiz = NULL;

  NW_GTPV2C_MALLOC(hStack, sizeof(nw_gtpv2c_msg_ie_parse_info_t), thiz,
                   nw_gtpv2c_msg_ie_parse_info_t *);

  if (thiz) {
    memset(thiz, 0, sizeof(nw_gtpv2c_msg_ie_parse_info_t));
    thiz->hStack = hStack;
    thiz->msgType = msgType;

    switch (msgType) {
      case NW_GTP_ECHO_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, echoRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CREATE_SESSION_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createSessionReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CREATE_SESSION_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createSessionRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_DELETE_SESSION_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteSessionReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_DELETE_SESSION_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteSessionRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_MODIFY_BEARER_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, modifyBearerReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CREATE_BEARER_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createBearerReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CREATE_BEARER_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createBearerRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_UPDATE_BEARER_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, updateBearerReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_UPDATE_BEARER_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, updateBearerRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_DELETE_BEARER_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteBearerReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_DELETE_BEARER_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteBearerRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_DELETE_BEARER_CMD: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteBearerCmdIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_DELETE_BEARER_FAILURE_IND: {
        rc =
            nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteBearerFailureIndIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_BEARER_RESOURCE_CMD: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, bearerResourceCmdIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_BEARER_RESOURCE_FAILURE_IND: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          bearerResourceFailureIndIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_MODIFY_BEARER_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, modifyBearerRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_RELEASE_ACCESS_BEARERS_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          releaseAccessBearersReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_RELEASE_ACCESS_BEARERS_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          releaseAccessBearersRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_FORWARD_RELOCATION_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_FORWARD_RELOCATION_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_FORWARD_ACCESS_CONTEXT_NTF: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          forwardAccessContextNtfIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_FORWARD_ACCESS_CONTEXT_ACK: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          forwardAccessContextAckIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_FORWARD_RELOCATION_COMPLETE_NTF: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(
            thiz, forwardRelocationCompleteNtfIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_FORWARD_RELOCATION_COMPLETE_ACK: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(
            thiz, forwardRelocationCompleteAckIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CONTEXT_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CONTEXT_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_CONTEXT_ACK: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextAckIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_RELOCATION_CANCEL_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          relocationCancelRequestIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_RELOCATION_CANCEL_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz,
                                          relocationCancelResponseIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_IDENTIFICATION_REQ: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, identificationReqIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      case NW_GTP_IDENTIFICATION_RSP: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, identificationRspIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      /** Paging related downlink data notification. */
      case NW_GTP_DOWNLINK_DATA_NOTIFICATION: {
        rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, downlinkDataNtfIeInfoTbl);
        NW_ASSERT(NW_OK == rc);
      } break;

      default: {
        free_wrapper((void **)&thiz);
        thiz = NULL;
      } break;
    }
  }

  return thiz;
}

/**
   Destructor
   @return NW_OK on success.
*/

nw_rc_t nwGtpv2cMsgIeParseInfoDelete(nw_gtpv2c_msg_ie_parse_info_t *thiz) {
  uint16_t ieInstance = 0;
  uint16_t ieType = 0;

  if (thiz) {
    /** Check if group info exists. */
    for (ieType = 0; ieType < NW_GTPV2C_IE_TYPE_MAXIMUM; ieType++) {
      for (ieInstance = 0; ieInstance < NW_GTPV2C_IE_INSTANCE_MAXIMUM;
           ieInstance++) {
        if (thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo)
          NW_GTPV2C_FREE(thiz->hStack,
                         thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo);
      }
    }
    NW_GTPV2C_FREE(thiz->hStack, thiz);
  }
  return NW_OK;
}

/**
   Parse message
   @return NW_OK on success.
*/

nw_rc_t nwGtpv2cMsgIeParse(NW_IN nw_gtpv2c_msg_ie_parse_info_t *thiz,
                           NW_IN nw_gtpv2c_msg_handle_t hMsg,
                           NW_INOUT nw_gtpv2c_error_t *pError) {
  nw_rc_t rc = NW_OK;
  uint16_t mandatoryIeCount = 0;
  uint8_t *pIeBufStart;
  uint8_t *pIeBufEnd;
  uint16_t ieType;
  uint16_t ieLength;
  uint16_t ieInstance;
  nw_gtpv2c_ie_tlv_t *pIe;
  nw_gtpv2c_msg_t *pMsg = (nw_gtpv2c_msg_t *)hMsg;
  uint8_t flags = *((uint8_t *)(pMsg->msgBuf));

  pIeBufStart = (uint8_t *)(pMsg->msgBuf + (flags & 0x08 ? 12 : 8));
  pIeBufEnd = (uint8_t *)(pMsg->msgBuf + pMsg->msgLen);
  // memset(pMsg->pIe, 0, sizeof(uint8_t*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) *
  // (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
  memset(pMsg->isIeValid, (false),
         sizeof(uint8_t) * (NW_GTPV2C_IE_TYPE_MAXIMUM) *
             (NW_GTPV2C_IE_INSTANCE_MAXIMUM));

  while (pIeBufStart < pIeBufEnd) {
    pIe = (nw_gtpv2c_ie_tlv_t *)pIeBufStart;
    ieType = pIe->t;
    ieLength = ntohs(pIe->l);
    ieInstance = pIe->i & 0x0F;
    NW_ASSERT(NW_GTPV2C_IE_INSTANCE_MAXIMUM >= ieInstance);
    OAILOG_DEBUG(
        LOG_GTPV2C,
        "Received IE %u with instance %u of length %u in msg-type %u!\n",
        ieType, ieInstance, ieLength, thiz->msgType);

    if (pIeBufStart + 4 + ieLength > pIeBufEnd) {
      OAILOG_ERROR(LOG_GTPV2C,
                   "Invalid length for IE of type %u and instance %u!\n",
                   ieType, ieInstance);
      pError->cause = NW_GTPV2C_CAUSE_INVALID_LENGTH;
      pError->offendingIe.type = ieType;
      pError->offendingIe.instance = ieInstance;
      return NW_FAILURE;
    }

    if ((thiz->ieParseInfo[ieType][ieInstance].iePresence)) {
      if ((ieLength < (thiz->ieParseInfo[ieType][ieInstance].ieMinLength))) {
        if (thiz->ieParseInfo[ieType][ieInstance].iePresence ==
            NW_GTPV2C_IE_PRESENCE_OPTIONAL) {
          /*
           * Ignore TLV
           */
          pIeBufStart += (ieLength + 4);
          continue;
        } else {
          pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT;
          pError->offendingIe.type = ieType;
          pError->offendingIe.instance = ieInstance;
          OAILOG_ERROR(LOG_GTPV2C,
                       "Mandatory IE of type %u and instance %u incorrect!\n",
                       ieType, ieInstance);
          return NW_FAILURE;
        }
      }

      if (pMsg->isIeValid[ieType][ieInstance] == true) {
        /*
         * If an information element is repeated in a GTP signalling
         * message in which repetition of the information element is
         * not specified, only the contents of the information element
         * appearing first shall be handled and all subsequent repetitions
         * of the information element shall be ignored.
         * TODO: Add handling for IEs for which repetition is allowed.
         */
        pIeBufStart += (ieLength + 4);
        continue;
      }

      pMsg->pIe[ieType][ieInstance] = (uint8_t *)pIeBufStart;
      pMsg->isIeValid[ieType][ieInstance] = true;

      if (thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo) {
        /*
         * Parse the grouped IE
         */
        rc = nwGtpv2cMsgGroupedIeParse(
            thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo, ieType,
            ieLength, ieInstance, ((uint8_t *)pIe) + 4);

        if (rc != NW_OK) {
          pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT;
          pError->offendingIe.type = ieType;
          pError->offendingIe.instance = ieInstance;
          OAILOG_ERROR(LOG_GTPV2C,
                       "Mandatory IE of type %u and instance %u incorrect!\n",
                       ieType, ieInstance);
          return NW_FAILURE;
        }
      }

      if (thiz->ieParseInfo[ieType][ieInstance].iePresence ==
          NW_GTPV2C_IE_PRESENCE_MANDATORY) {
        mandatoryIeCount++;
      }
    } else {
      OAILOG_WARNING(LOG_GTPV2C,
                     "Unexpected IE %u with instance %u of length %u received "
                     "in msg %u!\n",
                     ieType, ieInstance, ieLength, thiz->msgType);
    }

    pIeBufStart += (ieLength + 4);
  }

  if ((NW_OK == rc) && (mandatoryIeCount != thiz->mandatoryIeCount)) {
    for (ieType = 0; ieType < NW_GTPV2C_IE_TYPE_MAXIMUM; ieType++) {
      for (ieInstance = 0; ieInstance < NW_GTPV2C_IE_INSTANCE_MAXIMUM;
           ieInstance++) {
        if (thiz->ieParseInfo[ieType][ieInstance].iePresence ==
            NW_GTPV2C_IE_PRESENCE_MANDATORY) {
          if (pMsg->isIeValid[ieType][ieInstance] == false) {
            OAILOG_ERROR(LOG_GTPV2C,
                         "Mandatory IE of type %u and instance %u missing in "
                         "msg type %u\n",
                         ieType, ieInstance, pMsg->msgType);
            pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
            pError->offendingIe.type = ieType;
            pError->offendingIe.instance = ieInstance;
            return NW_FAILURE;
          }
        }
      }
    }

    OAILOG_CRITICAL(
        LOG_GTPV2C,
        "Unknown mandatory IE missing. Msg parser formed incorrectly!\n");
    pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
    pError->offendingIe.type = 0;
    pError->offendingIe.instance = 0;
    return NW_FAILURE;
  }

  pError->cause = NW_GTPV2C_CAUSE_REQUEST_ACCEPTED;
  return NW_OK;
}

#ifdef __cplusplus
}
#endif

/*--------------------------------------------------------------------------*
                            E N D   O F   F I L E
  --------------------------------------------------------------------------*/
